﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Threading;
using DbLinq.Data.Linq;
using EzDesk.DesktopClient.Model;
using EzDesk.DesktopClient.Event;
using EzDesk.DesktopClient.Storage;
using EzDesk.EventAggregation;
using EzDesk.Generic;

namespace EzDesk.DesktopClient
{
    /// <summary>
    /// @Refactory 
    /// </summary>
    public class ClientConfigurationManagement : ManagementBase<ClientConfigurationManagement>
    {

        private EzDesktopClientDb _clientDbContext;
       


        private const int FEED_DISPLAY_COUNT = 30;
        private const int DURATION_OF_GET_FEED = 1;
        private const bool IS_DISPLAY_READ_FEED = true;

        private readonly DateTime MIN_DATE = new DateTime(1900, 1, 1);

        public int DurationOfGetFeed
        {
            get
            {
                Configuration pair = GetConfigurationPair("DurationOfGetFeed", DURATION_OF_GET_FEED);
                return Convert.ToInt32(pair.Value);
            }
            set
            {
                this.UpdateSetPair("DurationOfGetFeed", value);
                RaisePropertyChanged("DurationOfGetFeed");
            }
        }
        public int FeedDisplayCount
        {
            get
            {
                Configuration pair = GetConfigurationPair("FeedDisplayCount", FEED_DISPLAY_COUNT);
                return Convert.ToInt32(pair.Value);
            }
            set
            {
                UpdateSetPair("FeedDisplayCount", value);
                RaisePropertyChanged("FeedDisplayCount");
            }
        }

        public bool IsDisplayReadFeed
        {
            get
            {
                Configuration pair = GetConfigurationPair("IsDisplayReadFeed", IS_DISPLAY_READ_FEED);
                return Convert.ToBoolean(pair.Value);
            }
            set
            {
                UpdateSetPair("IsDisplayReadFeed", value);
                RaisePropertyChanged("IsDisplayReadFeed");
            }
        }

        public DateTime LastLoadDatetime
        {
            get
            {
                Configuration pair = GetConfigurationPair("LastLoadDatetime", MIN_DATE.Ticks.ToString());
                return DateTime.FromBinary(Convert.ToInt64(pair.Value));
            }
            set
            {
                UpdateSetPair("LastLoadDatetime", value.Ticks.ToString(), true);
            }
        }


        private List<Configuration> _configurationSet;


        public ClientConfigurationManagement()
        {
            InitEvent();
        }

        private void InitEvent()
        {
            LoginEvent.Instance.Subscribe(this.OnUserLogin, ThreadOption.PublisherThread);
            LogoutEvent.Instance.Subscribe(this.OnUserLogout, ThreadOption.BackgroundThread);
        }

        private void OnUserLogin(LoginArgs args)
        {
            _clientDbContext = ClientDbStorage.GetDataContext(CurrentUser.UserCode);
            _configurationSet = _clientDbContext.Configuration.ToList();
        }

        private void OnUserLogout(LogoutArgs args)
        {
        }


        private Configuration GetConfigurationPair(string defaultKey, object defaultValue)
        {
            Configuration configuration = _configurationSet.FirstOrDefault(c => c.Key == defaultKey);

            if (configuration == null)
            {
                lock (this)
                {
                    configuration = _configurationSet.FirstOrDefault(c => c.Key == defaultKey);
                    if (configuration == null)
                    {
                        var temp = AddPair(defaultKey, defaultValue);
                        configuration = temp;
                        _configurationSet.Add(temp);
                    }
                }

            }

            return configuration;
        }

        private Configuration AddPair(string key, object value)
        {
            var pair = new Configuration() { Key = key, Value = value.ToString(), Type = value.GetType().ToString() };
            _clientDbContext.Configuration.InsertOnSubmit(pair);
            _clientDbContext.SubmitChanges();
            return pair;
        }

        private void UpdateSetPair(string key, object newValue, bool updateRightNow = false)
        {
            var pair = _configurationSet.FirstOrDefault(x => x.Key == key);
            pair.Value = newValue.ToString();

            if(_clientDbContext !=null)
                updateRightNow.TrueDo(_clientDbContext.SubmitChanges);
        }

        public void SaveConfiguration()
        {
            _clientDbContext.SubmitChanges();
        }
    }
}

